package com.metadata_system.api_server.system_server;


import com.metadata_system.api.annotations.CheckTokenUser;
import com.metadata_system.common.db.entity.Project;
import com.metadata_system.common.dto.ApiResult;
import com.metadata_system.common.http.request_dto.LoginUserRequest;
import com.metadata_system.system.request.ProjectListParams;
import com.metadata_system.system.service.ProjectService;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api/system-server/v001/Project/")
public class ProjectController {

    @Autowired
    private ProjectService projectService;
    @Autowired
    private LoginUserRequest loginUserRequest;

    @RequestMapping("getList")
    @CheckTokenUser
    public ApiResult getList(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer type,
            @RequestParam(required = false) Integer databaseId,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer pageSize,
            @RequestParam(required = false) String sortProp,
            @RequestParam(required = false) String sortOrder
    ) {
        ProjectListParams listParams = new ProjectListParams();
        listParams.setName(name);
        listParams.setType(type);
        listParams.setDatabaseId(databaseId);
        listParams.setPage(page);
        listParams.setPageSize(pageSize);
        listParams.setSortProp(sortProp);
        listParams.setSortOrder(sortOrder);
        listParams.setUserId(this.loginUserRequest.getTokenUser().decodeID());
        return this.projectService.getList(listParams);
    }

    @RequestMapping("getProjectUserList")
    @CheckTokenUser
    public ApiResult getProjectUserList(
            @RequestParam(required = false) Integer id
    ) {
        return this.projectService.getProjectUserList(id);
    }

    @RequestMapping("getNodeDataList")
    @CheckTokenUser
    public ApiResult getProjectNodeDataList(
            @RequestParam(required = false) Integer id,
            @RequestParam(required = false) Integer nodeId,
            @RequestParam(required = false) Map<String,Object> searchMap,
            @RequestParam(required = false, defaultValue = "1") Integer page,
            @RequestParam(required = false, defaultValue = "100") Integer pageSize,
            @RequestParam(required = false, defaultValue = "createdTime") String sortProp,
            @RequestParam(required = false, defaultValue = "desc") String sortOrder
    ) {
        return this.projectService.getNodeDataList(id, nodeId, page, pageSize, searchMap,sortProp,sortOrder);
    }

//    @RequestMapping("getNodeDataTotal")
//    public ApiResult getNodeDataTotal(
//            @RequestParam(required = false) Integer projectId,
//            @RequestParam(required = false) Integer nodeId,
//            @RequestParam(required = false) Map<String,String> searchMap
//    ) {
//        return this.projectService.getNodeDataTotal(projectId, nodeId, searchMap);
//    }

    @RequestMapping("getDetail")
    @CheckTokenUser
    public ApiResult getDetail(
            @RequestParam(required = false) Integer id
    ) {
        return this.projectService.getDetail(id,this.loginUserRequest.getTokenUser().decodeID());
    }

    /**
     * 创建项目
     *
     * @param name           项目名称
     * @param type           项目类型
     * @param description    项目描述
     * @param metadataId 元数据节点ID
     * @param users          项目用户
     * @return
     */
    @RequestMapping("create")
    @CheckTokenUser
    @Transactional
    public ApiResult create(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String shortName,
            @RequestParam(required = false) Integer type,
            @RequestParam(required = false) Integer databaseId,
            @RequestParam(required = false) String description,
            @RequestParam(required = false) Integer metadataId,
            @RequestParam(required = false) String users
    ) {
        ApiResult apiResult = this.projectService.create(Project.builder()
                .userId(loginUserRequest.getTokenUser().decodeID())
                .databaseId(databaseId)
                .name(name)
                .shortName(shortName)
                .type(type)
                .description(description)
                .metadataId(metadataId)
                .build(), users, loginUserRequest.getTokenUser().decodeID());
        if (apiResult.getCode()>0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return apiResult;
    }

    @RequestMapping("update")
    @CheckTokenUser
    @Transactional
    public ApiResult update(
            @RequestParam(required = false) Integer id,
            @RequestParam(required = false) Integer databaseId,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String shortName,
            @RequestParam(required = false) Integer type,
            @RequestParam(required = false) String description,
            @RequestParam(required = false) Integer metadataId,
            @RequestParam(required = false) String users
    ) {
        ApiResult apiResult = this.projectService.update(Project.builder()
                .id(id)
                .databaseId(databaseId)
                .name(name)
                .shortName(shortName)
                .type(type)
                .description(description)
                .metadataId(metadataId)
                .build(), users, loginUserRequest.getTokenUser().decodeID());
        if (apiResult.getCode()>0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return apiResult;
    }

    @RequestMapping("delete")
    @CheckTokenUser
    @Transactional
    public ApiResult delete(
            @RequestParam(required = false) Integer id
    ) {
        ApiResult apiResult = this.projectService.delete(id, loginUserRequest.getTokenUser().decodeID());
        if (apiResult.getCode()>0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return apiResult;
    }




    @SneakyThrows
    @RequestMapping("parseImportFile")
    @CheckTokenUser
    @Transactional
    public ApiResult parseImportFile(
            @RequestParam(required = false) String fileUrl,
            @RequestParam(required = false) Integer id
    ) {
        return this.projectService.importProjectNode(fileUrl, id);
    }


    @SneakyThrows
    @RequestMapping("history")
    @CheckTokenUser
    @Transactional
    public ApiResult history(
            @RequestParam(required = false) Integer id
    ) {
        return this.projectService.history(id,loginUserRequest.getTokenUser().decodeID());
    }

    @SneakyThrows
    @RequestMapping("export")
    @CheckTokenUser
    @Transactional
    public ApiResult export(
            @RequestParam(required = false) Integer id,
            @RequestParam(required = false) String nodeNames
    ) {
        return this.projectService.exportData(id,loginUserRequest.getTokenUser().decodeID(),nodeNames);
    }



}
